#!/usr/bin/env python

from django.utils import simplejson
from google.appengine.ext import webapp
from models.library import Library
from models.setting import Setting
import logging
from datetime import datetime
import uuid
from lib import isbn

# This controller handles the
# generation of the front page.

class AjaxHandler(webapp.RequestHandler):

    def writeResponse(self, result):
        output = simplejson.dumps(result)
        
        callback = self.request.get('callback')
        if callback:
            output = '%s(%s)' % (callback, output)
        
        self.response.out.write(output)
    

class LibrarySearchHandler(AjaxHandler):

    def get(self):
        
        search = self.request.get('q')
        limit = self.request.get('limit')
        offset = self.request.get('offset')
        problems = self.request.get('problems')
        sort = self.request.get('sort') or 'title'
        kind = self.request.get('kind')

        limit = int(limit) if limit else 100
        offset = int(offset) if offset else 0
            
        count_search = Library.count_search(search, kind, sort, limit, offset, problems)
        libs = []
        for lib in count_search["items"]:
            libs.append(lib.toDict())

        result = count_search
        result["items"] = libs
        
        super(LibrarySearchHandler, self).writeResponse(result)

class LibrarySaveHandler(AjaxHandler):

    def post(self):
        data = dict()
        
        data["name"] = self.request.get('name')
        data["title"] = self.request.get('title')
        data["link"] = self.request.get('link')
        data["have"] = self.request.get('have')
        data["dont"] = self.request.get('dont')
        if self.request.get('match_isbn') != '':
            data["match_isbn"] = True
        else:
            data["missing"] = self.request.get('missing')
        
        is_community = self.request.get('is_community')
        data["is_community"] = not (is_community in ['', 'false'])
        
        logging.info("Saving %s '%s'" % (data["name"], data["title"]))
        
        lib = Library.create(data)
        
#        lib.validate()

        lib.put()
        logging.info("lib put.")

        result = lib.toDict()
        super(LibrarySaveHandler, self).writeResponse(result)


class LibraryGetHandler(AjaxHandler):

    def get(self, name):
    
        result = dict()
        lib = Library.resolve(name)
        if lib:
            result["library"] = lib.toDict()
        super(LibraryGetHandler, self).writeResponse(result)

class LibraryDeleteHandler(AjaxHandler):

    def get(self, name):
    
        result = dict()
        
        lib = Library.resolve(name)
        if lib:
            lib.delete()
        else:
            result["error"] = "Library not found"

        super(LibraryDeleteHandler, self).writeResponse(result)

class LibraryNormalizeHandler(AjaxHandler):

    def get(self):
    
        q = Library.all()
        rs = q.fetch(2000, 0)
        
        result = dict()
        count_tested = 0
        count_has_problems = 0
        count_changed = 0
        for l in rs:
            changed = False
            has_problems = l.problems is not None
            if l.has_problems != has_problems:
                l.has_problems = has_problems
                changed = True
                count_has_problems += 1
                
            if not l.tested:
                l.tested = datetime.min
                changed = True
                count_tested += 1
            
            if changed:
                count_changed += 1
                l.put()
        
        result["count_changed"] = count_changed
        result["count_tested"] = count_tested
        result["count_has_problems"] = count_has_problems
        
        super(LibraryNormalizeHandler, self).writeResponse(result)

class LibraryValidateHandler(AjaxHandler):

    def get(self, name):
    
        result = dict()
        
        lib = Library.resolve(name)
        if lib:
            lib.validate()
            lib.put()
            result["library"] = lib.toDict()
        else:
            result["error"] = "Library not found"

        super(LibraryValidateHandler, self).writeResponse(result)

class LibraryTestHandler(AjaxHandler):

    def get(self):
        
        name = self.request.get('name')
        title = self.request.get('title')
        link = self.request.get('link')
        have = self.request.get('have')
        dont = self.request.get('dont')
        missing = self.request.get('missing')
        match_isbn = self.request.get('match_isbn')
        is_community = self.request.get('is_community').lower() == 'true'
        
        result = dict()

        logging.debug("TestHandler: %s" % (name,))

        existingLib = Library.resolve(name)
        if existingLib:
            result["existing"] = existingLib.toDict()
            logging.debug("Found Existing")
        else:
            logging.debug("Does not exist")
        
        try:
            lib = Library(name = name,
                    title = title,
                    link = link,
                    is_community = is_community,
                    have = have,
                    dont = dont)
                    
            if match_isbn != '':
                lib.match_isbn = True
            else:
                lib.missing = missing
                
            result["haveUrl"] = lib.siteUrl(have)
            result["dontUrl"] = lib.siteUrl(dont)
            result["library"] = lib.toDict()
            lib.validateLink()
            result["have"] = lib.process(have)
            result["dont"] = lib.process(dont)
            
        except Exception, ex:
            result["error"] = "%s" % (ex,)
                
        super(LibraryTestHandler, self).writeResponse(result)

class LibraryTestContributionHandler(AjaxHandler):

    def get(self):
        
        result = dict()
        
        disabled_contributions = Setting.get("disabled_contributions", False)
        
        if disabled_contributions:
            result["error"] = disabled_contributions
        
        else:
                
            name = uuid.uuid4().hex
            title = self.request.get('title')
            link = self.request.get('link')
            have = self.request.get('have')
            dont = self.request.get('dont')
            missing = self.request.get('missing')
            match_isbn = self.request.get('match_isbn')
            
            logging.debug("LibraryTestContributionHandler: %s" % (title,))
    
            existingLib = Library.find(title)
            
            if existingLib:
                result["existing"] = existingLib.toDict()
                logging.debug("Found Existing")
            else:
                logging.debug("Does not exist")
            
            try:
                lib = Library(name = name,
                        title = title,
                        link = link,
                        have = have,
                        dont = dont)
                        
                if match_isbn != '':
                    lib.match_isbn = True
                else:
                    lib.missing = missing
                    
                result["haveUrl"] = lib.siteUrl(have)
                result["dontUrl"] = lib.siteUrl(dont)
                result["library"] = lib.toDict()
                if not isbn.isValid(have):
                    raise Exception("Existing Book ISBN '%s' is not a valid!" % (have,))
                if not isbn.isValid(dont):
                    raise Exception("Missing Book ISBN '%s' is not a valid!" % (dont,))
                lib.validateLink()
                result["have"] = lib.process(have)
                result["dont"] = lib.process(dont)
                
            except Exception, ex:
                result["error"] = "%s" % (ex,)
                
        super(LibraryTestContributionHandler, self).writeResponse(result)
